package com.industry.framework.core.wrapper;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.industry.framework.core.wrapper.parameter.Conditions;
import com.industry.framework.core.wrapper.parameter.Orders;
import com.industry.framework.core.wrapper.parameter.Pages;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author nbZhuozh
 * @Date 2025-04-21  17:02
 **/
public class WrapperExtractor<T> {
    private static final String BASE_DEL_FLAG = "del_flag";
    private static final Logger log = LoggerFactory.getLogger(WrapperExtractor.class);
    /**
     * 当前记录起始索引 默认值
     */
    public static final int DEFAULT_PAGE_NUM = 1;

    /**
     * 每页显示记录数 默认值 默认查全部
     */
    public static final int DEFAULT_PAGE_SIZE = 80; //todo zzh：先这么写测试使用，下周改回来
    private final Class<T> entityClass;
    private QueryTableWrapper<T> queryTableWrapper;

    public WrapperExtractor(Class<T> entityClass) {
        this.entityClass = Objects.requireNonNull(entityClass, "Entity class cannot be null");
    }

    public QueryWrapper<T> queryWrapperBuilder(QueryTableWrapper<T> queryTableWrapper) {
        Objects.requireNonNull(queryTableWrapper, "QueryTableWrapper cannot be null");
        this.queryTableWrapper = queryTableWrapper;
        List<Conditions> conditionsList = queryTableWrapper.getCondition();
        if (CollectionUtils.isEmpty(conditionsList)) {
            log.warn("Empty conditions list provided");
            return new QueryWrapper<>();
        }
        QueryWrapper<T> wrapper = new QueryWrapper<>();
        //idoo 自带 作用逻辑删除查询、数据权限查询、租户同表数据隔离插叙
        baseAppend(wrapper);
        //idoo 业务查询
        serviceAppend(wrapper, conditionsList);
        return wrapper;
    }

    public Page<T> excuteRowBounds(){
        Objects.requireNonNull(queryTableWrapper, "QueryTableWrapper cannot be null");
        Pages page = this.queryTableWrapper.getPage();
        List<Orders> sort = this.queryTableWrapper.getSort();
        //构造分页参数
        return excuteRowBounds(page,sort);
    }

    /**
     * 查询前构造page对象
     * @param page page , List<Orders> orders
     * @return
     */
    public Page<T> excuteRowBounds(Pages page , List<Orders> orders){
        //构造orderItem
        List<OrderItem> orderItems = new ArrayList<>();
        if(!CollectionUtils.isEmpty(orders)){
            for (Orders order : orders) {
                if(!StringUtils.isEmpty(order.getFiled())){
                    if(StringUtils.equals("ASC",order.getOrderType().toUpperCase())){
                        orderItems.add(OrderItem.asc(order.getFiled()));
                    }
                    if(StringUtils.equals("DESC",order.getOrderType().toUpperCase())){
                        orderItems.add(OrderItem.desc(order.getFiled()));
                    }
                }
            }
        }
        //构造size 和 num
        Objects.requireNonNull(queryTableWrapper, "QueryTableWrapper cannot be null");
        Integer pageNum = ObjectUtil.defaultIfNull(page.getPageNum(), DEFAULT_PAGE_NUM);
        Integer pageSize = ObjectUtil.defaultIfNull(page.getPageSize(), DEFAULT_PAGE_SIZE);
        if (pageNum <= 0) { pageNum = DEFAULT_PAGE_NUM; }
        if (pageSize <= 0){ pageSize = DEFAULT_PAGE_SIZE; }
        Page<T> pagg = new Page<>(pageNum, pageSize);
        if (CollUtil.isNotEmpty(orderItems)) {
            pagg.addOrder(orderItems);
        }
        return pagg;
    }




    protected void baseAppend(QueryWrapper<T> wrapper) {
//        wrapper.eq(BASE_DEL_FLAG, "0");
        // TODO 拼接数据权限
        // TODO 拼接租户数据隔离
    }

    public void serviceAppend(QueryWrapper<T> wrapper, List<Conditions> conditionsList) {
        conditionsList.forEach(condition -> conditionBuilder(wrapper, condition));
    }

    protected void conditionBuilder(QueryWrapper<T> wrapper, Conditions condition) {
        if (condition == null || StringUtils.isEmpty(condition.getOperator())) {
            return;
        }

        String fieldName = condition.getField();

        List<Object> values = convertValues(condition.getValue(), condition.getValueType());
        if (CollectionUtils.isEmpty(values)) {
            return;
        }

        try {
            String casser = condition.getOperator().toUpperCase();
            switch (casser) {
                case "EQ" -> wrapper.in(fieldName, values);
                case "NEQ" -> wrapper.notIn(fieldName, values);
                case "LIKE" -> wrapper.and(w->{values.forEach(i->w.or().like(fieldName,i));});
                case "LIKE_LEFT" -> values.forEach(v -> wrapper.likeLeft(fieldName, v));
                case "NOT_LIKE" -> values.forEach(v -> wrapper.notLike(fieldName, v));
                case "IS_NULL" -> wrapper.isNull(fieldName);
                case "NOT_NULL" -> wrapper.isNotNull(fieldName);
                case "IN" -> wrapper.in(fieldName, values);
                case "NOT_IN" -> wrapper.notIn(fieldName, values);
                case "BETWEEN" -> {
                    if (values.size() >= 2) {
                        wrapper.between(fieldName, values.get(0), values.get(1));
                    }
                }
                case "NOT_BETWEEN" -> {
                    if (values.size() >= 2) {
                        wrapper.notBetween(fieldName, values.get(0), values.get(1));
                    }
                }
                default -> log.warn("Unsupported operator type: {}", condition.getOperator());
            }
        } catch (Exception e) {
            log.error("Error building condition for field {} with operator {}",
                    fieldName, condition.getOperator(), e);
        }
    }

    protected List<Object> convertValues(List<String> values, String type) {
        if (CollectionUtils.isEmpty(values) || StringUtils.isEmpty(type)) {
            return Collections.emptyList();
        }

        return values.stream()
                .map(val -> convertValue(val, type))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    protected Object convertValue(String val, String type) {
        if (val == null || type == null) {
            return null;
        }
        try {
            return switch (type.toLowerCase()) {
                case "string" -> val;
                case "integer", "int" -> Integer.parseInt(val);
                case "long" -> Long.parseLong(val);
                case "double" -> Double.parseDouble(val);
                case "float" -> Float.parseFloat(val);
                case "boolean" -> Boolean.parseBoolean(val);
                case "localdatetime" -> LocalDateTime.parse(val, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
                case "localdate" -> LocalDate.parse(val, DateTimeFormatter.ISO_LOCAL_DATE);
                case "localtime" -> LocalTime.parse(val, DateTimeFormatter.ISO_LOCAL_TIME);
                case "bigdecimal" -> new BigDecimal(val);
                case "date" -> new SimpleDateFormat("yyyy-MM-dd").parse(val);
                case "datetime" -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(val);
                default -> {
                    log.warn("Unsupported value type: {}", type);
                    yield null; //从 switch 表达式中返回一个值
                }
            };
        } catch (Exception e) {
            log.error("Error converting value {} to type {}", val, type, e);
            return null;
        }
    }
}
